import React, { useRef } from 'react'
import {
  Input,
  InputNumber,
  Button,
  Form,
  Select,
  Layout,
  Table,
  Col,
  DatePicker,
  Radio,
  Upload,
  Tag,
  Checkbox,
} from 'antd'
import GUtils from '@/utils'
import classNames from 'classnames'

const { TextArea } = Input
const { RangePicker } = DatePicker

const LdhInput = (props) => (
  <Input allowClear autoComplete="off" {...props}></Input>
)
const LdhPassword = (props) => (
  <Input.Password allowClear autoComplete="off" {...props}></Input.Password>
)
const LdhInputNumber = (props) => (
  <InputNumber autoComplete="off" {...props}></InputNumber>
)
const LdhTextArea = (props) => (
  <TextArea allowClear autoComplete="off" {...props}></TextArea>
)
const LdhButton = (props) => <Button {...props}></Button>

const LdhUpload = ({ children, ...rest }) => (
  <Upload {...rest}>{children}</Upload>
)
const LdhRadio = (props) => <Radio {...props}></Radio>

const LdhRadioGroup = ({ children, ...rest }) => (
  <Radio.Group {...rest}>{children}</Radio.Group>
)

const LdhMapRadioGroup = (props) => {
  let { map, type, isDetail, value, onChange, ...rest } = props
  map = map || window.ENUMS[type]
  let list = []
  for (let k in map) {
    list.push({ label: map[k], value: k })
  }
  if (isDetail) {
    return <div>{map[value]}</div>
  }
  return (
    <Radio.Group value={value} onChange={onChange} {...rest}>
      {list.map((o) => (
        <LdhRadio value={o.value} key={o.value}>
          {o.label}
        </LdhRadio>
      ))}
    </Radio.Group>
  )
}

const LdhDatePicker = (props) => <DatePicker {...props}></DatePicker>
const LdhRangePicker = (props) => <RangePicker allowClear {...props} />
const LdhSelect = (props) => {
  let { isDetail, value = '', label, options, addAll, mode } = props
  if (['tags', 'multiple'].includes(mode)) {
    if (!value || value == '') {
      value = []
    } else if (Array.isArray(value)) {
      value = value.map((o) => o + '')
    } else {
      value = value.split(',')
    }
  } else {
    value = value + ''
  }
  options.forEach((o) => (o.value = o.value + ''))
  if (isDetail) {
    if (!label) {
      if (!value) {
        label = ''
      } else if (Array.isArray(value)) {
        return options
          .filter((o) => value.includes(o.value))
          .map((o) => <Tag key={o.value}>{o.label}</Tag>)
      } else {
        for (let o of options) {
          if (o.value == value) {
            label = o.label
            break
          }
        }
      }
    }

    return <div>{label}</div>
  }
  if (addAll) {
    options = [{ label: '全部', value: '' }, ...options]
  }
  return (
    <Select
      showSearch
      allowClear
      {...props}
      value={value}
      options={options}
    ></Select>
  )
}
const LdhListSelect = (props) => {
  let { list = [], ...rest } = props
  let options = list.map((e) => ({ label: e, value: e }))
  return <LdhSelect options={options} {...rest}></LdhSelect>
}
const LdhObjListSelect = (props) => {
  let { list = [], valueField = 'id', labelField = 'name', ...rest } = props
  let options = list.map((e) => ({
    label: e[labelField],
    value: e[valueField],
  }))
  return <LdhSelect options={options} {...rest}></LdhSelect>
}
const LdhBooleanSelect = (props) => {
  let { list, type, ...rest } = props
  list = list || window.ENUMS[type]
  let options = [
    { value: true, label: list[0] },
    { value: false, label: list[1] },
  ]
  return <LdhSelect options={options} {...rest}></LdhSelect>
}
const LdhMapSelect = (props) => {
  let { map, type = '', ...rest } = props
  map = map || window.ENUMS[type]
  let options = []
  for (let k in map) {
    options.push({ label: map[k], value: k })
  }
  return <LdhSelect options={options} {...rest}></LdhSelect>
}

const LdhForm = React.forwardRef((props, ref) => {
  let { labelWidth, children, ...rest } = props

  return (
    <Form
      ref={ref}
      labelCol={{ flex: labelWidth }}
      wrapperCol={{ flex: 1 }}
      layout="horizontal"
      {...rest}
    >
      {children}
    </Form>
  )
})

const LdhFormItemValue = (props) => {
  let { value, checked, isCheckbox, isSelect, options = [] } = props

  if (isCheckbox) {
    return <Checkbox disabled checked={checked}></Checkbox>
  } else if (isSelect) {
    const option = options?.find((v) => v.value === value || v.id === value)
    return <div>{option?.label || option?.name || ''}</div>
  }

  return <div>{value}</div>
}
const LdhFormItem = (props) => {
  let {
    isDetail,
    name,
    hideLabel,
    label,
    required,
    isCheckbox,
    isSelect,
    checkboxValueType,
    children,
    value,
    rules = [],
    options = [],
    ...rest
  } = props

  if (required) {
    rules.push({ required: true })
  }
  if (isCheckbox) {
    rest.className = 'check-item'
    rest.valuePropName = 'checked'
  }
  label = label || name
  if (hideLabel) label = null
  return (
    <Form.Item
      name={name}
      label={label}
      required={required}
      rules={rules}
      {...rest}
    >
      {/* <LdhFormItemValue isDetail={isDetail}>{children}</LdhFormItemValue>*/}
      {isDetail ? (
        <LdhFormItemValue
          isCheckbox={isCheckbox}
          isSelect={isSelect}
          options={options}
        />
      ) : (
        children
      )}
    </Form.Item>
  )
}
const LdhFormItemTip = ({ children, className }) => (
  <div className={classNames('form-item-tip', className)}>{children}</div>
)

// 提示信息
let messageApi = null
const Message = {
  init(m) {
    messageApi = m
  },
  open(type, content, duration = 3) {
    messageApi.open({ type, content, duration })
  },
  success(content) {
    this.open('success', content)
  },
  info(content) {
    this.open('info', content)
  },
  warning(content) {
    this.open('warning', content)
  },
  error(content) {
    this.open('error', content)
  },
}

const LdhLog = React.forwardRef((props, ref) => {
  const logRef = useRef()
  React.useImperativeHandle(ref, () => ({
    add(e) {
      let log = e.detail
      let line = document.createElement('div')

      let { type, time, key, msg } = log
      line.className = type
      line.innerText = `${time} 【${key}】 ${msg}`
      logRef.current.appendChild(line)
    },
  }))
  return <div className="ldh-log" ref={logRef} {...props}></div>
})

const { Header, Content, Footer, Sider } = Layout

/**
 * sortFields [],支持排序的字段
 * @param props
 * @returns {*}
 * @constructor
 */
const onSort = (f, a, b) => ((a[f] || '') > (b[f] || '') ? 1 : -1)
const buildColumn = (title, key, width, props) => {
  let { sortable, ...rest } = props || {}
  let sorter
  if (sortable) {
    sorter = onSort.bind(this, key)
  }
  return { title: title, key: key, dataIndex: key, width, sorter, ...rest }
}

const COL_NO = buildColumn('序号', 'index', 60, {
  render: (v, vo, index) => index + 1,
})
const COL_OP = buildColumn('操作', 'action')
const LdhTable = (props) => {
  let { columns, sortFields, ...rest } = props
  if (sortFields) {
    columns.forEach((c) => {
      if (sortFields.includes(c.key)) {
        c.sorter = onSort.bind(this, c.key)
      }
    })
  }
  return (
    <Table bordered columns={columns} scroll={{ y: true }} {...rest}></Table>
  )
}
export {
  LdhInput,
  LdhPassword,
  LdhInputNumber,
  LdhTextArea,
  LdhDatePicker,
  LdhRangePicker,
  LdhButton,
  LdhUpload,
  LdhRadio,
  LdhRadioGroup,
  LdhMapRadioGroup,
  LdhSelect,
  LdhListSelect,
  LdhObjListSelect,
  LdhMapSelect,
  LdhBooleanSelect,
  LdhForm,
  LdhFormItem,
  LdhFormItemTip,
  Message,
  buildColumn,
  COL_NO,
  COL_OP,
  LdhLog,
  LdhTable,
}
